/*
 * @Description: 
 * @Author: Junhuang
 * @Date: 2022-02-15 10:01:08
 * @LastEditTime: 2022-03-21 20:09:06
 * @LastEditors: Junhuang
 * @Reference: 
 */

'use strict';

const await = require('await-stream-ready/lib/await');

const { apiSuccesss, apiFail } = require('../extend/context');

const Controller = require('egg').Controller;

// 参数校验规则
const rules = {
  title: { type: 'string', required: true, desc: '视频标题' },
  cover: { type: 'string', required: true, desc: '封面' },
  category_id: { type: 'int', required: true, desc: '分类ID' },
  description: { type: 'string', required: true, desc: '描述' },
}

class VideoController extends Controller {
  //新增作品
  async save() {
    const { ctx, app } = this;
    const { title, cover, category_id, description, duration, play_count, danmu_count } = ctx.request.body;
    let user_id = ctx.authUser.id;
    // 参数验证
    ctx.validate(rules);


    let video = await app.model.Video.create({
      title, cover, category_id, description, user_id, duration, play_count, danmu_count
    });

    // console.log('video=', video);
    return ctx.apiSuccesss(video);
  }

  //更新作品
  // 路由(动态)：‘/video/:id’
  async update() {
    const { ctx, app } = this;
    let currentUser = ctx.authUser;
    ctx.validate({
      id: {
        required: true,
        type: 'int',
        desc: '作品id'
      },
      ...rules
    })

    let {
      title,
      cover,
      category_id,
      description
    } = ctx.request.body;

    let video = await app.model.Video.findOne({
      where: {
        id: ctx.params.id,
        user_id: currentUser.id
      }
    })

    if (!video) {
      return ctx.throw(404, '该记录不存在');
    }

    let res = await video.update({
      title,
      cover,
      category_id,
      description
    })

    return ctx.apiSuccesss(res);
  }

  // 路由/video/:id/edit
  async edit() {
    const { ctx, app, service } = this;
    let currentUser = ctx.authUser;
    ctx.validate({
      id: {
        type: 'int',
        required: true,
        desc: '作品id'
      }
    });
    let { id } = ctx.params;

    let video = await app.model.Video.findOne({
      where: {
        id
      },
      include: [{
        model: app.model.Category,
        attributes: [['id', 'category_id'], 'title', 'cover', 'description']
      }, {
        model: app.model.VideoDetail
      }]
    });

    if (!video) {
      return ctx.apiFail('无此作品');
    }
    // 判断当前作品是否属于当前登录用户
    if (video.user_id != currentUser.id) {
      return ctx.apiFail('该作品不属于您');
    }
    let v = JSON.parse(JSON.stringify(video));
    return ctx.apiSuccesss(video);
  }

  // 删除作品，并同时删除视频+评论+收藏
  // 路由：/video/destroy
  async del() {
    const { ctx, app } = this;
    let currentUser = ctx.authUser;
    ctx.validate({
      id: {
        type: 'int',
        required: true,
        desc: '作品id'
      }
    });
    let { id } = ctx.request.body;
    let video = await app.model.Video.findOne({
      where: {
        id,
        user_id: currentUser.id
      }
    })
    if (!video) {
      return ctx.throw(404, '该记录不存在');
    }
    let transaction;
    try {
      // 建立事务对象
      transaction = await this.ctx.model.transaction();
      // 删除视频
      let res = await this.ctx.model.VideoDetail.destroy({
        where: {
          video_id: id
        },
        transaction
      });
      console.log('VideoDetail:', res);
      // 删除评论
      res = await this.ctx.model.Comment.destroy({
        where: {
          video_id: id
        },
        transaction
      });
      console.log('Comment:', res);
      // 删除收藏
      res = await this.ctx.model.Fava.destroy({
        where: {
          video_id: id
        },
        transaction
      });
      console.log('Fava:', res);
      // 删除作品
      res = await this.ctx.model.Video.destroy({
        where: {
          id
        },
        transaction
      });
      console.log('video:', res);
      // ctx.throw('400', 'transaction error');
      await transaction.commit();
      return ctx.apiSuccesss('删除视频成功');
    } catch (err) {
      console.log(err);
      await transaction.rollback();
      return ctx.apiFail('删除视频失败' + err);
    }
  }

  // 获取作品基本信息
  // 路由：/video_get/:id
  async get() {
    const { ctx, app } = this;
    ctx.validate({
      id: {
        type: 'int',
        required: true,
        desc: '作品id'
      }
    });
    let { id } = ctx.params;
    let video = await app.model.Video.findByPk(id);
    if (!video) {
      return ctx.apiFail('无此作品');
    }
    return ctx.apiSuccesss(video);
  }

  // 作品详情-用户登录后访问
  async read_auth() {
    console.log('read_auth')
    await this.read()
  }

  // 作品详情-用户未登录时访问
  async read() {
    const { ctx, app, service } = this;
    let currentUser = ctx.authUser;

    ctx.validate({
      id: {
        type: 'int',
        required: true,
        desc: '作品id'
      }
    });

    let { id } = ctx.params;

    let video = await app.model.Video.findOne({
      where: {
        id
      },
      include: [{
        model: app.model.VideoDetail
      }, {
        model: app.model.Category,
        attributes: [['id', 'category_id'], 'title', 'cover', 'description']
      }, {
        model: app.model.User,
        attributes: [['id', 'user_id'], 'username', 'nickname', 'avatar']
      }]
    });

    if (!video) {
      return ctx.apiFail('无此作品');
    }

    // 最热门的5条作品
    let hot = await this.hot(id);

    // 是否收藏
    let fava = false;
    // 是否关注
    let follow = false;
    // 粉丝数
    let fansCount = await service.user.getFanCount(video.user_id);

    // 如果当前用户已经登录
    if (currentUser) {
      // 注意此处两个!是将findOne的返回对象promise转换为Boolean对象
      // console.log('##################is_fava =', video.id, currentUser.id);
      fava = !!(await app.model.Fava.findOne({
        where: {
          video_id: video.id,
          user_id: currentUser.id
        }
      }));

      // 当前登录用户是否关注了指定作品的用户 
      follow = await service.user.isFollow(currentUser.id, video.user_id);
    }
    ctx.apiSuccesss({ video, hot, fava, follow, fansCount });
  }

  // 热门视频
  async hot(id) {
    const { app } = this;
    const Op = app.Sequelize.Op;
    // 如果id不存在，则将id设置为0
    if (!id) { id = 0; }
    return await app.model.Video.findAll({
      where: {
        id: {
          [Op.ne]: id
        }
      },
      order: [
        ['id', 'DESC'],
        ['play_count', 'DESC']
      ],
      limit: 5
    });
  }

  //指定用户的作品列表,不需要登录即可访问
  //路由（动态）：'/video_list/:page'
  //示例：http://127.0.0.1:7001/video_list/1?limit=10&user_id=1
  async index() {
    const { ctx, app } = this;

    // 参数验证
    ctx.validate({
      user_id: {
        required: true,
        type: 'int',
        desc: '用户id'
      },
      page: {
        required: true,
        type: 'int',
        desc: '第几页'
      },
      limit: {
        required: false,
        type: 'int',
        desc: '每页几条'
      }
    });

    let user_id = ctx.query.user_id;

    //console.log('user_id=', user_id);

    let res = await ctx.page(ctx.model.Video, { user_id },
      {
        attributes: {
          include: [
            [
              app.Sequelize.literal(`(select count(1) vcount from  video_detail vd WHERE  vd.video_id = video.id)`),
              'detail_count'
            ]
          ]
        }
      });
    // let res = await ctx.model.Video.findAll({
    //   where: {
    //     user_id
    //   },
    //   attributes: {
    //     include: [
    //       [
    //         app.Sequelize.literal(`(select count(1) vcount from  video_detail vd WHERE  vd.video_id = video.id)`),
    //         'detail_count'
    //       ]
    //     ]
    //   }
    // })

    //ctx.sleep(3000);

    return ctx.apiSuccesss(res);

  }

  //搜索作品,不需要登录即可访问
  //路由（动态）：'/video_search/:page'
  //示例：http://127.0.0.1:7001/video_search/1?keyword=traveller&limit=10
  async search() {
    const { ctx, app } = this;

    // 参数验证
    ctx.validate({
      keyword: {
        required: true,
        type: 'string',
        desc: '关键字'
      },
      page: {
        required: true,
        type: 'int',
        desc: '第几页'
      },
      limit: {
        required: false,
        type: 'int',
        desc: '每页几条'
      }
    });

    let keyword = ctx.query.keyword;

    let Op = app.Sequelize.Op;

    let res = await ctx.page(ctx.model.Video,
      {
        title: {
          [Op.like]: '%' + keyword + '%'
        }
      },
      {
        attributes: {
          include: [
            [
              app.Sequelize.literal(`(select count(1) vcount from  video_detail vd WHERE  vd.video_id = video.id)`),
              'detail_count'
            ]
          ]
        }
      });

    return ctx.apiSuccesss(res);
  }

  // 指定分类下的作品列表
  // 路由（动态）：'/category/:category_id/video/:page'
  // 示例：http://127.0.0.1:7001/category/1/video/1?limit=10
  async list() {
    const { ctx, app } = this;
    // 目前validate可能有问题，调用validate后query可能会丢失，
    // 因此如果要使用myquery避免错误，特别是要用到分页，就需要把query先存储一下
    ctx.myquery = ctx.query;
    ctx.validate({
      category_id: {
        type: 'int',
        required: true,
        desc: '分类id'
      },
      page: {
        type: 'int',
        required: true,
        desc: '页码'
      }
    });
    let category_id = ctx.params.category_id;
    let rows = await ctx.page(app.model.Video, {
      category_id,
    }, {
      include: [{
        model: app.model.Category,
        attributes: [['id', 'category_id'], 'title', 'cover', 'description']
      }]
    });

    let res = JSON.parse(JSON.stringify(rows));
    res.forEach(item => {
      item.category_title = item.category.title;
    });

    return ctx.apiSuccesss(res);
  }
}

module.exports = VideoController;
